package com.example.coolweather;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.coolweather.db.County;
import com.example.coolweather.gson.Forecast;
import com.example.coolweather.gson.Weather;
import com.example.coolweather.util.HttpUtil;
import com.example.coolweather.util.Utility;
import com.google.gson.Gson;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.function.Predicate;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

public class WeatherActivity extends AppCompatActivity {

    private ScrollView weatherLayout;

    private TextView titleCity;

    private TextView titleUpdateTime;

    private TextView degreeText;

    private TextView weatherInfoText;

    private LinearLayout forecastLayout;

    private TextView aqiText;

    private TextView pm25Text;

    private TextView comfortText;

    private TextView carWashText;

    private TextView sportText;

    /**
     * author: the_ring
     * Time: 2021/5/2 17:06
     * log: 设定四个参数，当三个请求都执行完时，采取显示数据
     */
    private boolean nowRunned = false;
    private boolean forecastRunned = false;
    private boolean aqiRunned = false;
    private boolean indicesRunned = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_weather);

        // 初始化控件
        weatherLayout = findViewById(R.id.weather_layout);
        titleCity = findViewById(R.id.title_city);
        titleUpdateTime = findViewById(R.id.title_update_time);
        degreeText = findViewById(R.id.degree_text);
        weatherInfoText = findViewById(R.id.weather_info_text);
        forecastLayout = findViewById(R.id.forecast_layout);
        aqiText = findViewById(R.id.aqi_text);
        pm25Text = findViewById(R.id.pm25_text);
        comfortText = findViewById(R.id.comfort_text);
        carWashText = findViewById(R.id.car_wash_text);
        sportText = findViewById(R.id.sport_text);

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        String weatherString = prefs.getString("weather", null);
        if (weatherString != null) {
            // 有缓存时直接解析数据
            Weather weather = new Gson().fromJson(weatherString, Weather.class);
            showWeatherInfo(weather);
        } else {
            // 无缓存时去服务器查询天气
            String countyId = getIntent().getStringExtra("countyId");
            String countyName = getIntent().getStringExtra("countyName");
            weatherLayout.setVisibility(View.INVISIBLE);
//            requestWeather(countyId, countyName);
            new RequestWeather().execute(new String[]{"countyId:" + countyId, "countyName:" + countyName});

        }
    }

    /**
     * author: the_ring
     * Time: 2021/5/2 18:26
     * log: 使用一个 内部类实现异步请求
     */
    public class RequestWeather extends AsyncTask<String, Void, JSONObject> {

        JSONObject weather = null;
        CountDownLatch latch = null;


        @Override
        protected void onPreExecute() {
            weather = new JSONObject();
            latch = new CountDownLatch(4);
        }


        @Override
        protected JSONObject doInBackground(String... strings) {
            try {
                for (String string : strings) {
                    if (string.split(":")[0].equals("countyName")) {
                        weather.put("cityName", string.split(":")[1]);
                    } else if (string.split(":")[0].equals("countyId")) {

                        String countyId = string.split(":")[1];
                        String nowUrl = "https://devapi.qweather.com/v7/weather/now?" +
                                "key=4ef2ec0b926b44f39f40e85b589cffbc&range=cn" +
                                "&location=" + countyId;
                        Log.d("WeatherActivity", "nowUrl:" + nowUrl);
                        /**
                         * author: the_ring
                         * Time: 2021/5/2 15:27
                         * log: 解析获取当日信息
                         */
                        HttpUtil.sendOkHttpRequest(nowUrl, new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(WeatherActivity.this, "获取当前天气信息失败",
                                                Toast.LENGTH_LONG).show();
                                    }
                                });
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                try {
                                    String responseText = response.body().string();
                                    Log.d("WeatherActivity", "now responseText:" + responseText);
                                    JSONObject responseObject = new JSONObject(responseText);
                                    String code = responseObject.getString("code");
                                    Log.d("WeatherActivity", "now code:" + code);
                                    System.out.println();
                                    if (code.equals("200")) {
                                        String updateTime = responseObject.getString("updateTime");
                                        String temperature = responseObject.getJSONObject("now").getString("temp");
                                        String info = responseObject.getJSONObject("now").getString("text");
                                        weather.put("updateTime", updateTime);
                                        weather.put("temperature", temperature);
                                        weather.put("info", info);
                                        Log.d("WeatherActivity", "updateTime" + updateTime);
                                        Log.d("WeatherActivity", "temperature:" + temperature);
                                        Log.d("WeatherActivity", "info:" + info);

                                        nowRunned = true;

                                        latch.countDown();
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }

                        });
                        Log.d("WeatherActivity", "weather:" + weather.toString());
                        /**
                         * author: the_ring
                         * Time: 2021/5/2 15:34
                         * log: 获取 7 天的 天气
                         */
                        String forecastUrl = "https://devapi.qweather.com/v7/weather/3d?" +
                                "key=4ef2ec0b926b44f39f40e85b589cffbc&range=cn" +
                                "&location=" + countyId;
                        HttpUtil.sendOkHttpRequest(forecastUrl, new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(WeatherActivity.this, "获取7天天气信息失败",
                                                Toast.LENGTH_LONG).show();
                                    }
                                });
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                try {
                                    String responseText = response.body().string();
                                    Log.d("WeatherActivity", "forecast responseText:" + responseText);
                                    JSONObject responseObject = new JSONObject(responseText);
                                    String code = responseObject.getString("code");
                                    Log.d("WeatherActivity", "forecast code:" + code);
                                    System.out.println();
                                    if (code.equals("200")) {
                                        JSONArray dailyArray = responseObject.getJSONArray("daily");
                                        weather.put("forecast", dailyArray);

                                        forecastRunned = true;

                                        latch.countDown();
                                    }

                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                        Log.d("WeatherActivity", "weather:" + weather.toString());
                        /**
                         * author: the_ring
                         * Time: 2021/5/2 16:06
                         * log: 获取空气质量状况
                         */
                        String aqiUrl = "https://devapi.qweather.com/v7/air/now?" +
                                "key=4ef2ec0b926b44f39f40e85b589cffbc&range=cn" +
                                "&location=" + countyId;
                        Log.d("WeatherActivity", "aqiUrl" + aqiUrl);
                        HttpUtil.sendOkHttpRequest(aqiUrl, new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(WeatherActivity.this, "获取空气质量信息失败",
                                                Toast.LENGTH_LONG).show();
                                    }
                                });
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                try {
                                    String responseText = response.body().string();
                                    Log.d("WeatherActivity", "aqi responseText:" + responseText);
                                    JSONObject responseObject = new JSONObject(responseText);
                                    String code = responseObject.getString("code");
                                    Log.d("WeatherActivity", "aqi code:" + code);
                                    System.out.println();
                                    if (code.equals("200")) {
                                        String aqi = responseObject.getJSONObject("now").getString("aqi");
                                        String pm25 = responseObject.getJSONObject("now").getString("pm2p5");
                                        weather.put("aqi", aqi);
                                        weather.put("pm25", pm25);

                                        aqiRunned = true;
                                        latch.countDown();

                                        Log.d("abc:aqi", String.valueOf(Thread.currentThread().getId()));
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                        Log.d("WeatherActivity", "weather:" + weather.toString());

                        /**
                         * author: the_ring
                         * Time: 2021/5/2 16:12
                         * log: 获取生活指数
                         */
                        String indicesUrl = "https://devapi.qweather.com/v7/indices/1d?" +
                                "key=4ef2ec0b926b44f39f40e85b589cffbc&range=cn" +
                                "&type=1,2,3" +
                                "&location=" + countyId;
                        Log.d("WeatherActivity", "indicesUrl:" + indicesUrl);
                        HttpUtil.sendOkHttpRequest(indicesUrl, new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(WeatherActivity.this, "获取生活指数信息失败",
                                                Toast.LENGTH_LONG).show();
                                    }
                                });
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                try {
                                    String responseText = response.body().string();
                                    Log.d("WeatherActivity", "indices responseText:" + responseText);
                                    JSONObject responseObject = new JSONObject(responseText);
                                    String code = responseObject.getString("code");
                                    Log.d("WeatherActivity", "indices code:" + code);
                                    System.out.println();
                                    if (code.equals("200")) {
                                        JSONArray indicesArray = responseObject.getJSONArray("daily");
                                        String comfort = "";
                                        String carWash = "";
                                        String sport = "";
                                        for (int i = 0; i < indicesArray.length(); i++) {
                                            JSONObject jsonObject = indicesArray.getJSONObject(i);
                                            if (1 == jsonObject.getInt("type")) {
                                                sport = jsonObject.getString("category") + "："
                                                        + jsonObject.getString("text");
                                            } else if (2 == jsonObject.getInt("type")) {
                                                carWash = jsonObject.getString("category") + "："
                                                        + jsonObject.getString("text");
                                            } else if (3 == jsonObject.getInt("type")) {
                                                comfort = jsonObject.getString("category") + "："
                                                        + jsonObject.getString("text");
                                            }

                                        }
                                        weather.put("comfort", comfort);
                                        weather.put("carWash", carWash);
                                        weather.put("sport", sport);
                                        Log.d("WeatherActivity", "comfort:" + comfort);
                                        Log.d("WeatherActivity", "carWash:" + carWash);
                                        Log.d("WeatherActivity", "sport:" + sport);

                                        indicesRunned = true;
                                        latch.countDown();
                                        Log.d("abc:indivinces", String.valueOf(Thread.currentThread().getId()));
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                        Log.d("WeatherActivity", "weather:" + weather.toString());
                    }
                }
                latch.await();
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (nowRunned == true && forecastRunned == true && aqiRunned == true && indicesRunned == true) {
                return weather;
            }
            return null;
        }

        @Override
        protected void onPostExecute(JSONObject jsonObject) {
            final Weather weather1 = new Gson().fromJson(String.valueOf(weather), Weather.class);
            if (weather1 != null) {
                SharedPreferences.Editor editor = PreferenceManager
                        .getDefaultSharedPreferences(WeatherActivity.this)
                        .edit();
                Log.d("WeatherActivity", weather.toString());
                editor.putString("weather", weather.toString());
                editor.apply();
                showWeatherInfo(weather1);
            } else {
                Toast.makeText(WeatherActivity.this, "获取天气信息失败",
                        Toast.LENGTH_LONG).show();
            }
        }

    }


    /**
     * 根据天气 id 请求城市天气信息
     */
    /**
     * author: the_ring
     * Time: 2021/5/2 15:38
     * log: 使用 Map 存储数据无法存储数组
     */
    public void requestWeather(final String countyId, final String countyName) {
        try {

            /**
             * author: the_ring
             * Time: 2021/5/2 17:41
             * log: 使用 CountDownLatch 控制运行
             */
            final CountDownLatch latch = new CountDownLatch(4);

//        Map<String, String> weather = new HashMap<>();
//        weather.put("cityName", countyName);
            JSONObject weather = new JSONObject();
            weather.put("cityName", countyName);
            String nowUrl = "https://devapi.qweather.com/v7/weather/now?" +
                    "key=4ef2ec0b926b44f39f40e85b589cffbc&range=cn" +
                    "&location=" + countyId;
            Log.d("WeatherActivity", "nowUrl:" + nowUrl);
            /**
             * author: the_ring
             * Time: 2021/5/2 15:27
             * log: 解析获取当日信息
             */
            HttpUtil.sendOkHttpRequest(nowUrl, new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(WeatherActivity.this, "获取当前天气信息失败",
                                    Toast.LENGTH_LONG).show();

                            latch.countDown();
                        }
                    });
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    try {
                        String responseText = response.body().string();
                        Log.d("WeatherActivity", "now responseText:" + responseText);
                        JSONObject responseObject = new JSONObject(responseText);
                        String code = responseObject.getString("code");
                        Log.d("WeatherActivity", "now code:" + code);
                        System.out.println();
                        if (code.equals("200")) {
                            String updateTime = responseObject.getString("updateTime");
                            String temperature = responseObject.getJSONObject("now").getString("temp");
                            String info = responseObject.getJSONObject("now").getString("text");
                            weather.put("updateTime", updateTime);
                            weather.put("temperature", temperature);
                            weather.put("info", info);
                            Log.d("WeatherActivity", "updateTime" + updateTime);
                            Log.d("WeatherActivity", "temperature:" + temperature);
                            Log.d("WeatherActivity", "info:" + info);

                            nowRunned = true;
                            latch.countDown();
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

            });
            Log.d("WeatherActivity", "weather:" + weather.toString());
            /**
             * author: the_ring
             * Time: 2021/5/2 15:34
             * log: 获取 7 天的 天气
             */
            String forecastUrl = "https://devapi.qweather.com/v7/weather/3d?" +
                    "key=4ef2ec0b926b44f39f40e85b589cffbc&range=cn" +
                    "&location=" + countyId;
            HttpUtil.sendOkHttpRequest(forecastUrl, new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(WeatherActivity.this, "获取7天天气信息失败",
                                    Toast.LENGTH_LONG).show();

                            latch.countDown();
                        }
                    });
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    try {
                        String responseText = response.body().string();
                        Log.d("WeatherActivity", "forecast responseText:" + responseText);
                        JSONObject responseObject = new JSONObject(responseText);
                        String code = responseObject.getString("code");
                        Log.d("WeatherActivity", "forecast code:" + code);
                        System.out.println();
                        if (code.equals("200")) {
                            JSONArray dailyArray = responseObject.getJSONArray("daily");
                            weather.put("forecast", dailyArray);

                            forecastRunned = true;

                            latch.countDown();
                        }

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
            Log.d("WeatherActivity", "weather:" + weather.toString());
            /**
             * author: the_ring
             * Time: 2021/5/2 16:06
             * log: 获取空气质量状况
             */
            String aqiUrl = "https://devapi.qweather.com/v7/air/now?" +
                    "key=4ef2ec0b926b44f39f40e85b589cffbc&range=cn" +
                    "&location=" + countyId;
            Log.d("WeatherActivity", "aqiUrl" + aqiUrl);
            HttpUtil.sendOkHttpRequest(aqiUrl, new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(WeatherActivity.this, "获取空气质量信息失败",
                                    Toast.LENGTH_LONG).show();

                            latch.countDown();
                        }
                    });
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    try {
                        String responseText = response.body().string();
                        Log.d("WeatherActivity", "aqi responseText:" + responseText);
                        JSONObject responseObject = new JSONObject(responseText);
                        String code = responseObject.getString("code");
                        Log.d("WeatherActivity", "aqi code:" + code);
                        System.out.println();
                        if (code.equals("200")) {
                            String aqi = responseObject.getJSONObject("now").getString("aqi");
                            String pm25 = responseObject.getJSONObject("now").getString("pm2p5");
                            weather.put("aqi", aqi);
                            weather.put("pm25", pm25);

                            aqiRunned = true;
                            latch.countDown();
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
            Log.d("WeatherActivity", "weather:" + weather.toString());

            /**
             * author: the_ring
             * Time: 2021/5/2 16:12
             * log: 获取生活指数
             */
            String indicesUrl = "https://devapi.qweather.com/v7/indices/1d?" +
                    "key=4ef2ec0b926b44f39f40e85b589cffbc&range=cn" +
                    "&location=" + countyId;
            Log.d("WeatherActivity", "indicesUrl:" + indicesUrl);
            HttpUtil.sendOkHttpRequest(indicesUrl, new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(WeatherActivity.this, "获取生活指数信息失败",
                                    Toast.LENGTH_LONG).show();

                            latch.countDown();
                        }
                    });
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    try {
                        String responseText = response.body().string();
                        Log.d("WeatherActivity", "indices responseText:" + responseText);
                        JSONObject responseObject = new JSONObject(responseText);
                        String code = responseObject.getString("code");
                        Log.d("WeatherActivity", "indices code:" + code);
                        System.out.println();
                        if (code.equals("200")) {
                            JSONArray indicesArray = responseObject.getJSONArray("daily");
                            String comfort = "";
                            String carWash = "";
                            String sport = "";
                            for (int i = 0; i < indicesArray.length(); i++) {
                                JSONObject jsonObject = indicesArray.getJSONObject(i);
                                if (1 == jsonObject.getInt("type")) {
                                    sport = jsonObject.getString("category") + "："
                                            + jsonObject.getString("text");
                                } else if (2 == jsonObject.getInt("type")) {
                                    carWash = jsonObject.getString("category") + "："
                                            + jsonObject.getString("text");
                                } else if (3 == jsonObject.getInt("type")) {
                                    comfort = jsonObject.getString("category") + "："
                                            + jsonObject.getString("text");
                                }

                            }
                            weather.put("comfort", comfort);
                            weather.put("carWash", carWash);
                            weather.put("sport", sport);
                            Log.d("WeatherActivity", "comfort:" + comfort);
                            Log.d("WeatherActivity", "carWash:" + carWash);
                            Log.d("WeatherActivity", "sport:" + sport);

                            indicesRunned = true;
                            latch.countDown();
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
            Log.d("WeatherActivity", "weather:" + weather.toString());

            /**
             * author: the_ring
             * Time: 2021/5/2 16:36
             * log: 存储信息
             */
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
//                    try {
//                        latch.await();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }

                    final Weather weather1 = new Gson().fromJson(String.valueOf(weather), Weather.class);
                    if (weather1 != null && nowRunned == true && forecastRunned == true &&
                            aqiRunned == true && indicesRunned == true) {
                        SharedPreferences.Editor editor = PreferenceManager
                                .getDefaultSharedPreferences(WeatherActivity.this)
                                .edit();
                        Log.d("WeatherActivity", weather.toString());
                        editor.putString("weather", weather.toString());
                        editor.apply();
                        showWeatherInfo(weather1);
                    } else {
                        Toast.makeText(WeatherActivity.this, "获取天气信息失败",
                                Toast.LENGTH_LONG).show();
                    }
                }
            });
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理并展示 Weather 实体类中的数据
     */
    private void showWeatherInfo(Weather weather) {
        Log.d("WeatherActivity", weather.toString());
        String cityName = weather.getCityName();
        /**
         * author: the_ring
         * Time: 2021/5/2 16:47
         * log: 时间转化
         */
//        Log.d("WeatherActivity", weather.getUpdateTime());
        String updateTime = weather.getUpdateTime().substring(0, 15)
                .replace("T", " ");
        String degree = weather.getTemperature() + "℃";
        String weatherInfo = weather.getInfo();
        titleCity.setText(cityName);
        titleUpdateTime.setText(updateTime);
        degreeText.setText(degree);
        weatherInfoText.setText(weatherInfo);
        forecastLayout.removeAllViews();
        for (Forecast forecast : weather.getForecast()) {
            View view = LayoutInflater.from(this).inflate(R.layout.forecast_item, forecastLayout, false);
            TextView dateText = view.findViewById(R.id.date_text);
            TextView infoText = view.findViewById(R.id.info_text);
            TextView maxText = view.findViewById(R.id.max_text);
            TextView minText = view.findViewById(R.id.min_text);
            dateText.setText(forecast.getFxdate());
            infoText.setText(forecast.getTextDay());
            maxText.setText(forecast.getTempmax());
            minText.setText(forecast.getTempmin());
            forecastLayout.addView(view);
        }

        aqiText.setText(weather.getAqi());
        pm25Text.setText(weather.getPm25());

        String comfort = "舒适度：" + weather.getComfort();
        String carWash = "洗车指数：" + weather.getCarWash();
        String sport = "运动建议：" + weather.getSport();
        comfortText.setText(comfort);
        carWashText.setText(carWash);
        sportText.setText(sport);
        weatherLayout.setVisibility(View.VISIBLE);
    }
}